home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Business Master (3rd Edition)
/
The Business Master (3rd Edition).iso
/
files
/
utilreen
/
booklet
/
chop50.asm
< prev
next >
Wrap
Assembly Source File
|
1987-09-26
|
11KB
|
324 lines
PAGE 80,132
TITLE Chop file into 50K chunks
IF1
%OUT PASS1
ENDIF
IF2
%OUT PASS2
ENDIF
;
CHOP50 SEGMENT
ASSUME CS:CHOP50,DS:CHOP50,SS:CHOP50,ES:CHOP50
ORG 02H
TOPMEM DW ?
ORG 82H
PARM DB ?
ORG 100H
START: JMP REALSTART
HIMSG DB 'CHOP50 v1.1',0DH,0AH
DB ' Copyright 1987 Ronald Tansky',0DH,0AH,'$'
BADFILE DB 'COULD NOT OPEN INPUT FILE',0DH,0AH,'$'
BADOUT DB 'ERROR DURING WRITE',0DH,0AH,'$'
BADSPACE DB 'INSUFFICIENT DISK SPACE FOR WRITE',0DH,0AH,'$'
BADMEM DB 'INSUFFICIENT MEMORY- 64K minimum',0DH,0AH,'$'
BADOUTF DB 'ERROR OPENING OUTPUT FILE',0DH,0AH,'$'
SUFFIX0 DB '.000',0,0DH,0AH,'$'
EVEN
HANDLE1 DW ?
HANDLE2 DW ?
ENDOUT DW ? ; Pointer to trailing zero in FILENA2
LASTNO DW ? ; Pointer to last digit of FILENA2 suffix
OUTLEN DW 0 ; Length of output block
OUTLEN2 DW 0 ; Length of output block beyond last CR
OUT2POS DW 0 ; Position of data in output block past last CR
SAVEPOS DW FILENAME ; Position to start copy for FILENA2
EVEN
FILENAME DB 80 DUP(?)
FILENA2 DB 80 DUP(?)
;
; write opening message
;
REALSTART:
MOV DX,OFFSET HIMSG
MOV AH,9
INT 21H
;
; check for enough memory
;
MOV AX,TOPMEM
CMP AX,4096 ; 64K available?
JAE STPARSE ; yes, continue
JMP NOMEM ; no, abend
;
; fix file name
;
STPARSE: CLD
CALL PARSE1
MOV AL,[FILENAME]
CMP AL,0 ; null filename?
JNE OPEN1 ; no, open the file
JMP BADINPUT ; yes, don't even try to run
;
; open input file
;
OPEN1: MOV AH,3DH ; DOS open-file request code
MOV AL,40H ; full-share, read-only
MOV DX,OFFSET FILENAME
INT 21H
JNC FILEOK
JMP BADINPUT ; if error, to to error routine
FILEOK: MOV HANDLE1,AX ; save file handle
MOV BX,AX ; put in BX, also, as req'd for read
;
; Open output file
;
CALL BUMPFILE
MOV AH,3CH ; DOS create-file request code
MOV CX,0 ; no special attributes
MOV DX,OFFSET FILENA2
INT 21H
JNC FILE2G1
JMP BADOUTOP ; if error, to to error routine
FILE2G1: MOV HANDLE2,AX ; save file handle
;
; MAIN LOOP: read 50K, write it
;
READBLK:
MOV AH,3FH ; DOS request for read
MOV CX,51200 ; for 50K bytes
MOV BX,HANDLE1 ; from file using HANDLE1
MOV DX,OFFSET IOAREA ; into IOAREA
INT 21H
CMP AX,0 ; EOF?
JE CLOSE ; yes, close and end
CMP CX,AX ; full block read?
JNE LASTBLK ; no, write out last block
MOV AH,0BH ; dummy KB check to allow DOS BREAK
INT 21H
; write the block
CALL BRKBLK ; try to break block at last CR
MOV AH,40H ; DOS request for write
MOV CX,OUTLEN ; for about 50K bytes
MOV BX,HANDLE2 ; to file using HANDLE2
MOV DX,OFFSET IOAREA ; from IOAREA
INT 21H
JNC WCOM2 ; if write good, continue to next
JMP OUTERR
WCOM2: CMP AX,CX ; full block written?
JE NEXT2 ; yes
JMP NODASD ; no, error
;
; close current output and open next
;
NEXT2:
MOV AH,3EH
INT 21H
CALL BUMPFILE ; increment file suffix
MOV AH,3CH ; DOS create-file request code
MOV CX,0 ; no special attributes
MOV DX,OFFSET FILENA2
INT 21H
JC BADOUTOP ; if error, to to error routine
FILE2OK: MOV HANDLE2,AX ; save file handle
MOV AX,OUTLEN2
CMP AX,0 ; ANY RESIDUAL BLOCK?
JE NORESID
; Write residual data from last block
MOV CX,AX
MOV DX,OUT2POS
MOV AH,40H ; DOS request for write
MOV BX,HANDLE2 ; to file using HANDLE2
INT 21H
JNC WCOM3 ; if write good, continue to next
JMP OUTERR
WCOM3: CMP AX,CX ; full block written?
JE NORESID ; yes
JMP NODASD ; no, error
NORESID: JMP READBLK
LASTBLK:
MOV CX,AX ; for length in AX
MOV AH,40H ; DOS request for write
MOV BX,HANDLE2 ; to file using HANDLE2
MOV DX,OFFSET IOAREA ; from IOAREA
INT 21H
JNC WCOM4 ; if write good, continue to next
JMP OUTERR
WCOM4: CMP AX,CX ; full block written?
JE CLOSE ; yes
JMP NODASD ; no, error
CLOSE:
MOV BX,[HANDLE2]
MOV AH,3EH
INT 21H
MOV BX,[HANDLE1]
MOV AH,3EH
INT 21H
MOV AH,4CH
MOV AL,0
INT 21H
;
; error routines
;
BADINPUT: ; yes, or other error - end pgm
MOV DX,OFFSET BADFILE
RETBAD: MOV AH,9
INT 21H
MOV AH,4CH
MOV AL,8
INT 21H
NODASD: MOV DX,OFFSET BADSPACE
JMP RETBAD
OUTERR: MOV DX,OFFSET BADOUT
JMP RETBAD
BADOUTOP: MOV DX,OFFSET BADOUTF
JMP RETBAD
NOMEM: MOV DX,OFFSET BADMEM
JMP RETBAD
;
; parse parm into filename
; should be at least one non-blank character
;
PARSE1 PROC
LEA SI,PARM
FINDBLNK: LODSB
CMP AL,' ' ; leading blank?
JE FINDBLNK ; yes, ignore
LEA DI,FILENAME ; no, start moving file name
LOOKCR: CMP AL,0DH ; found CR yet?
JE ENDFN ; yes, move zero to end
CMP AL,' ' ; trailing blank?
JE ENDFN ; yes, end scan
CMP AL,":" ; is it a colon?
JE MARKPOS ; yes, mark this position
CMP AL,"\" ; is it a back slash?
JE MARKPOS ; yes, mark this position
NXTFN1: STOSB ; no, move byte to FILENAME field
LODSB
JMP LOOKCR
MARKPOS: MOV SAVEPOS,DI
INC SAVEPOS
JMP NXTFN1
ENDFN: MOV BYTE PTR[DI],0
;
; scan input file, through end or first '.'
; set suffix to '.000'
;
MOV BL,':' ; set default end-char
LEA DI,FILENA2 ; set pointer to beginning of filename2
CMP AL,0DH ; any operand 2?
JNE FINDB2 ; maybe
JMP NOOP2 ; no, move op 1
FINDB2: LODSB
CMP AL,' ' ; leading blank?
JE FINDB2 ; yes, ignore
LOOKCR2: CMP AL,0DH ; found CR yet?
JE ENDOP2 ; yes, move zero to end
CMP AL,' ' ; trailing blank?
JE ENDOP2 ; yes, end scan
CMP AL,'.' ; final '.'?
JE ENDOP2 ; yes, end scan
STOSB
MOV BL,AL ; hold on to last good char
LODSB
JMP LOOKCR2
ENDOP2: MOV AL,BL
CMP AL,':' ; did it end with ":"?
JE MOVEOP1 ; yes, move entire operand 1
CMP AL,'\' ; did it end with "\"?
JE MOVEOP1 ; yes, move entire operand 1
JMP ADDSUF ; no, just tack on suffix
NOOP2: MOV DI,OFFSET FILENA2
MOVEOP1: MOV SI,[SAVEPOS]
FINDDOT: LODSB
CMP AL,0 ; end of filename?
JE ADDSUF ; yes, add on the suffix
CMP AL,'.' ; start of suffix?
JE ADDSUF ; yes, replace with '.000'
STOSB ; no, move input char to output name
JMP FINDDOT
ADDSUF: MOV SI,OFFSET SUFFIX0
MOV CX,8
REP MOVSB
SUB DI,4
MOV ENDOUT,DI ; save pointer to trailing 0
DEC DI
MOV LASTNO,DI ; save pointer to last digit
RET
PARSE1 ENDP
;
; increment filename suffix by 1
;
BUMPFILE PROC
SUB AX,AX
MOV CX,3
MOV BX,ENDOUT
MOV SI,LASTNO
CLC
MOV AL,[SI]
ADC AL,1
JMP SHORT AAA1
ADDNEXT: MOV AL,[SI]
ADC AL,0
AAA1: AAA
PUSHF
OR AL,30H
POPF
MOV BYTE PTR[SI],AL
DEC SI
LOOP ADDNEXT
MOV BYTE PTR[BX],' '
MOV AH,9
MOV DX,OFFSET FILENA2
INT 21H ; print name of output file
MOV BYTE PTR[BX],0
RET
BUMPFILE ENDP
;
; trim block to last CR, if reasonable
;
BRKBLK PROC
MOV CX,256 ; if no CR with 256 bytes, forget it
STD
MOV SI,OFFSET IOAREA+51199 ; point to last byte of IOAREA
FINDBK: LODSB
CMP AL,0DH ; is it a CR?
JE GOTBRK ; yes, handle it
CMP AL,0AH ; is it a LF?
JE GOTBRK ; yes, handle it
LOOP FINDBK ; no, try prev char
; no CR within 256 bytes. set fields for full-length write
MOV CX,51200
MOV OUTLEN,CX
SUB AX,AX
MOV OUTLEN2,AX
JMP BRKBLKR
; Found a CR, set new lengths
GOTBRK: MOV BX,OFFSET IOAREA-2
MOV AX,SI
SUB AX,BX
MOV OUTLEN,AX
MOV AX,256
SUB AX,CX
MOV OUTLEN2,AX
INC SI
INC SI
MOV OUT2POS,SI
BRKBLKR: CLD
RET
BRKBLK ENDP
IOAREA DB ? ; IOAREA is 50K in size
CHOP50 ENDS
END START